﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using Debug = System.Diagnostics.Debug;

namespace Piao
{


    public partial class MainForm : Form
    {
        private delegate void UpdateFormControlDelegate(object arg);


        Func<Image, string> captchaHandle;//initialized in ctor.
        private static Mutex threadMutex = new Mutex(false, "{69082C9C-0783-41B8-BC32-BD5556F10D09}");

        DateTime lastPress = DateTime.Today;
        string pressed = string.Empty;

        int WORKER_TIMEOUT_MINUTES = 60;
        int ORDER_DAY_AHEAD = 11;
        Win7ProcessIcon win7SuperIcon = new Win7ProcessIcon();

        public MainForm()
        {

            InitializeComponent();

            InitializeBackgroundWorker();
            InitializeControlsFromSetting();
            InitializeCaptchaDelegate();


#if DEBUG
            this.Text += " - DEBUG VERSION";
#endif
        }


        private void txt_userFromStation_Autocompletion(object sender, KeyPressEventArgs e)
        {
            ComboBox box = (sender as ComboBox);
            BindingSource filterSource = box.DataSource as BindingSource;
            if (filterSource == null)
                return;

            //reset all columns
            if (e.KeyChar == (char)Keys.Escape)
            {
                if (box.SelectedIndex > 0)
                {
                    string text = box.Text;
                    filterSource.Filter = string.Empty;
                    box.Text = text;
                }
                else
                    filterSource.Filter = string.Empty;

                e.Handled = true;

                return;
            }

            //only accept valid input [a-zA-Z]
            //65-90 97-122

            bool onlyLetters = (e.KeyChar >= (char)65 && e.KeyChar <= (char)90) || (e.KeyChar >= (char)97 && e.KeyChar <= (char)122);
            if (!onlyLetters)
                return;

            //timeout to clear cached input
            TimeSpan ts = DateTime.Now - lastPress;
            if (ts.TotalSeconds > 1)
            {
                pressed = string.Empty;
            }

            lastPress = DateTime.Now;
            pressed += e.KeyChar.ToString().ToUpper();

            //dont use empty data source , the combox will throw ArgumentOutofRangeException
            //before that there is an empty row added in the table, it will be default item when search has no result
            string searchQuery = string.Format("[{0}] like '{1}%'", Global.DataComlumnPinYin, pressed);
            if (Global.StationNameTable.Select(searchQuery).Length == 0)
                searchQuery = string.Format("[{0}] is null", Global.DataComlumnPinYin);

            Log.Debug("filter by {0}", searchQuery);
            filterSource.Filter = searchQuery;

            //only handle the first char for navigation
            if (pressed.Length != 1)
                e.Handled = true;

            Debug.WriteLine(pressed);
        }

        private void txt_webCaptcha_KeyPressForFilter(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == (char)Keys.Back || e.KeyChar == (char)Keys.Delete)
                return;

            if (txt_webCaptcha.Text.Length >= 4)
            {
                e.Handled = true;
                return;
            }

            if ((e.KeyChar < '0' && e.KeyChar > '9')
                || (e.KeyChar < 'a' && e.KeyChar > 'z')
                || (e.KeyChar < 'A' && e.KeyChar > 'Z')
                || (e.KeyChar == ' ')
                )
                e.Handled = true;
        }

        /// <summary>
        /// read server city names.
        /// </summary>
        private void StartPrep()
        {
            Log.Debug("start:after logon init.");
            UpdateFormControlDelegate initialzeStationThreadDelegate = new UpdateFormControlDelegate(arg =>
            {
                if (Global.StationNameDict.Count == 0)
                {
                    MessageBox.Show("未能初始化，关闭并重启窗口再试。", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }

                try
                {
                    //here assign data source only once
                    if (txt_userFromStation.DataSource == null)
                    {
                        Log.Debug("apply data source to controls");
                        BindingSource bindSourceFrom = new BindingSource();
                        BindingSource bindSourceTo = new BindingSource();

                        //use different data source
                        bindSourceFrom.DataSource = Global.StationNameTable;
                        bindSourceTo.DataSource = Global.StationNameTable.Copy();

                        txt_userFromStation.DataSource = bindSourceFrom;
                        txt_userFromStation.ValueMember = Global.DataComlumnDisplayText;

                        txt_userToStation.DataSource = bindSourceTo;
                        txt_userToStation.ValueMember = Global.DataComlumnDisplayText;
                    }

                    txt_userFromStation.Enabled = true;
                    txt_userToStation.Enabled = true;
                    txt_userFromStation.Text = Configurations.txt_userFromStation;
                    txt_userToStation.Text = Configurations.txt_userToStation;
                }
                catch (Exception exc)
                {
                    Log.Debug(exc.ToString());
                }

            });


            UpdateFormControlDelegate initialzeSeatTypesThreadDelegate = new UpdateFormControlDelegate(arg =>
                {
                    Log.Debug("refresh seat types.");
                    List<JsonObject> list = arg as List<JsonObject>;
                    if (list == null || list.Count == 0)
                        return;


                    try
                    {
                        foreach (JsonObject obj in list)
                        {
                            if (chk_userSeatTypes.Items.Contains(obj.value) == false)
                            {
                                chk_userSeatTypes.Items.Add(obj.value);
                            }
                        }

                        if (chk_userSeatTypes.Items.Count > 2)
                        {
                            chk_userSeatTypes.SetItemChecked(0, true);
                            chk_userSeatTypes.SetItemChecked(1, true);
                        }
                        Log.Debug("end:select first seat as default.");

                        txt_userToStation_QueryStStrainAll(txt_userToStation, EventArgs.Empty);
                    }
                    catch (Exception exc)
                    {
                        Log.Debug(exc.ToString());
                    }


                });


            UpdateFormControlDelegate initialzeControlDisplayThreadDelegate = new UpdateFormControlDelegate(arg =>
                {
                    Log.Debug("end:app init is complete.");
                    menu_status.Text = "Ready";
                    this.TopMost = false;
                    group_captcha.Enabled = true;
                    group_login.Enabled = true;
                    group_ticket.Enabled = true;
                    group_webform.Enabled = true;
                });


            Thread thPrep = new Thread(() =>
            {
                int i = 0;
                while (i++ < 2)
                {
                    if (Global.StationNameDict.Count == 0)
                        UserOpration.Instance.QueryStationName();
                    else if (Global.TicketCodeList.Count == 0)
                        UserOpration.Instance.QuerySeatTypes();
                    else
                        break;

                    CheckThreadStateToAbort();
                    Thread.Sleep(1000);
                }


                this.Invoke(initialzeStationThreadDelegate, Global.StationNameDict);
                this.Invoke(initialzeSeatTypesThreadDelegate, Global.TicketCodeList);
                this.Invoke(initialzeControlDisplayThreadDelegate, "");

            });

            thPrep.Start();
        }

        private void btn_login_Click(object sender, EventArgs e)
        {
            Log.Debug("start:log in");
            this.btn_login.Enabled = false;

            txt_webCaptcha.Focus();
            string user = txt_userWebName.Text;
            string pwd = txt_userWebPassword.Text;


            UpdateFormControlDelegate loginComplete = new UpdateFormControlDelegate(arg =>
            {
                string welcomename = arg as string;
                user_imageBox.Image = null;
                lbl_userCaptchaInfo.Text = string.Empty;
                txt_webCaptcha.Text = null;
                btn_login.Enabled = true;
                btn_login.Focus();

                if (!string.IsNullOrEmpty(welcomename))
                {
                    this.Text = arg.ToString();
                    menu_status.Text = "登陆成功";

                    menu_start.ForeColor = Color.Red;
                    menu_start.Enabled = true;
                    StartPrep();
                    Log.Message("已登陆， 等待加载成功后点击 {0} 刷新； 站名首字母查询不支持多音字。", menu_start.Text);
                }

                Log.Debug("log in action is complete.");
            });


            Thread waitInputThread = new Thread(() =>
            {
                string propmtString = string.Empty;
                for (int i = 0; i < int.MaxValue; i++)
                {
                    //retry logon for 3 times if failed
                    propmtString = UserOpration.NewInstance().Login(captchaHandle, user, pwd);
                    if (!string.IsNullOrEmpty(propmtString))
                        break;
                }
                this.Invoke(loginComplete, propmtString);


            });

            waitInputThread.SetApartmentState(ApartmentState.STA);
            waitInputThread.Start();

        }

        private void txt_userToStation_QueryStStrainAll(object sender, EventArgs e)
        {
            if (txt_userToStation.SelectedIndex < 0 ||
                txt_userFromStation.SelectedIndex < 0 ||
                string.IsNullOrEmpty(txt_userToStation.Text) ||
                string.IsNullOrEmpty(txt_userFromStation.Text))
                return;

            if (txt_dateTimePicker.Value <= DateTime.Today)
            {
                Log.Error("日期需要大于今日. ");
                return;
            }

            Log.Debug("start:search trains.");

            txt_userTrains.Items.Clear();
            txt_userTrains.Enabled = false;
            txt_userOrderTrainName.Text = string.Empty;
            txt_userOrderTicketLeft.Text = string.Empty;



            string day = txt_dateTimePicker.Value.ToString("yyyy-MM-dd");

            //first one is initial letter for index
            string fromText = txt_userFromStation.Text.Split(',')[1];
            string toText = txt_userToStation.Text.Split(',')[1];

            //already in dropdown so index won't be out of bound.
            string fromCode = FindCodeByChineseName(fromText);
            string toCode = FindCodeByChineseName(toText);

            if (fromCode == toCode) return;

            if (txt_userFromStation.SelectedIndex < 0 || txt_userToStation.SelectedIndex < 0)
            {
                txt_userTrains.Enabled = false;
                return;
            }



            SetWorkStatus(true);

            UpdateFormControlDelegate initializeTrainListThreadDelegate = new UpdateFormControlDelegate(arg =>
            {
                try
                {
                    Log.Debug("start:set data to controls for seat types.");



                    Comparison<JsonObject> compareDelegate = delegate(JsonObject x, JsonObject y)
                    {
                        if (x.value[0] == y.value[0])
                        { return 0; }

                        int result = x.value[0] > y.value[0] ? -1 : 1;
                        return result;
                    };


                    List<object> extraNames = new List<object>();
                    List<JsonObject> source = arg as List<JsonObject>;
                    source.Sort(compareDelegate);

                    foreach (JsonObject item in source)
                    {
                        if (item.end_station_name == toText) //put exact match to the beginning and put the rest to end 
                            txt_userTrains.Items.Add(item.value);
                        else
                            extraNames.Add(item.value);
                    }


                    txt_userTrains.Items.AddRange(extraNames.ToArray<object>());


                    if (txt_userTrains.Items.Count > 0)
                    {
                        txt_userTrains.Enabled = true;
                        if (txt_userTrains.Items.Contains(Configurations.txt_userTrains))
                        {
                            txt_userTrains.SelectedItem = Configurations.txt_userTrains;
                        }
                        else
                            txt_userTrains.SelectedIndex = 0;

                        Log.Debug("end:retrieve train list is complete.");
                        txt_userTrains.Focus();
                    }
                    else
                    {
                        Log.Error("[{0}] 到 [{1}] 车次信息暂无。", fromText, toText);
                    }
                }
                catch (Exception ex)
                {
                    Log.Debug(ex.ToString());
                }
                finally
                {
                    SetWorkStatus(false);
                }
            });

            Thread thPrep = new Thread(() =>
            {
                if (threadMutex.WaitOne(TimeSpan.Zero))
                {
                    try
                    {
                        object stationData = UserOpration.Instance.QueryStStrainAll(day, fromCode, toCode);
                        this.Invoke(initializeTrainListThreadDelegate, stationData);
                    }
                    finally
                    {
                        threadMutex.ReleaseMutex();
                    }
                }
                else
                {
                    Log.Debug("Thread is busy, job of this thread is aborted. from {0} to {1}", fromText, toText);
                }

            });

            thPrep.SetApartmentState(ApartmentState.STA);
            thPrep.Start();

        }



        /// <summary>
        /// get train info by id. 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void txt_userTrains_QueryLeftTickets(object sender, EventArgs e)
        {
            if (txt_dateTimePicker.Value <= DateTime.Today)
            {
                Log.Error("日期需要大于今日. ");
                return;
            }

            lst_trainDetail.Items.Clear();
            txt_userOrderTicketLeft.Text = "";
            txt_userOrderTrainName.Text = "";


            if (txt_userTrains.SelectedIndex < 0)
            {
                this.lst_trainDetail.Tag = null;
                return;
            }
            Log.Debug("start:query left tickets");


            string trainId = txt_userTrains.SelectedItem.ToString();
            var train = Global.TrainCodeList.Find(t => t.value == trainId);

            if (train == null)
            {
                this.lst_trainDetail.Tag = null;
                return;
            }

            try
            {


                SetWorkStatus(true);
                //query left ticket
                string day = txt_dateTimePicker.Value.ToString("yyyy-MM-dd");
                string from = FindCodeByChineseName(txt_userFromStation.Text.Split(',')[1]);
                string to = FindCodeByChineseName(txt_userToStation.Text.Split(',')[1]);

                //set data tag
                OrderData odata = new OrderData()
                {
                    station_train_code = train.value,
                    train_date = day,
                    seattype_num = "",
                    from_station_telecode = from,
                    to_station_telecode = to,
                    include_student = "00",
                    from_station_telecode_name = "始发站",
                    to_station_telecode_name = "目的站",
                    round_train_date = "",
                    round_start_time_str = "00:00--24:00",
                    single_round_type = "1",
                    train_pass_type = "QB",
                    train_class_arr = "QB#D#Z#T#K#QT#",
                    start_time_str = "00:00--24:00",
                    lishi = train.lishi,
                    train_start_time = train.start_time,
                    trainno = train.id,
                    arrive_time = "15:42",
                    from_station_name = "始发站",
                    to_station_name = "目的站",
                    ypInfoDetail = train.ypInfoDetail,
                };



                txt_userOrderTrainName.Text = train.value;
                //station chinese name to code after output
                bool result = UserOpration.Instance.QueryLeftTicket(day, ref from, ref to, train.id, ref odata);
                txt_userOrderTicketLeft.Text = result ? "有" : "无";
                Log.Debug("end: query left ticket, attach object data to tag.");

                //update listview with property 'lishi'
                var propList = train.GetType().GetFields(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);

                foreach (var p in propList)
                {
                    string val = p.GetValue(train) as string;
                    var item = new ListViewItem(p.Name);
                    item.SubItems.Add(val);
                    lst_trainDetail.Items.Add(item);
                }



                this.lst_trainDetail.Tag = odata;


            }
            catch (Exception ex)
            {
                Log.Debug(ex.ToString());
            }
            finally
            { SetWorkStatus(false); }


        }


        private void menu_start_Click(object sender, EventArgs e)
        {
            Log.Debug("start:timer enabled for search.");
            Global.SeatTypeTargets = new List<JsonObject>();
            foreach (var checkeditem in chk_userSeatTypes.CheckedItems)
            {
                JsonObject obj = null;
                if (
                    (obj = Global.TicketCodeList.Find(j => j.value == checkeditem.ToString()))
                    != null)
                {
                    Global.SeatTypeTargets.Add(obj);
                    continue;
                }
            }

            if (Global.SeatTypeTargets.Count == 0)
            {
                MessageBox.Show("需要选择票类型", "Error");
                return;
            }
            if (lst_trainDetail.Tag == null)
            {
                MessageBox.Show("需要选择一个列车, 等待加载或选择。", "Error");
                return;
            }

            SetWorkStatus(true);

            UserData user = new UserData();
            //user.passenger_1_seat = tickets[0].id;
            user.passenger_1_ticket = "1"; //成人
            user.passenger_1_name = txt_userSeatName.Text;
            user.passenger_1_cardtype = "1";//二代身份证
            user.passenger_1_cardno = txt_userIdNumber.Text;
            user.passenger_1_mobileno = txt_userSeatTel.Text;

            this.backgroundWorker1.RunWorkerAsync(user);
        }

        private void menu_cancel_Click(object sender, EventArgs e)
        {
            Log.Debug("start:timer abort signal sent.");
            if (this.backgroundWorker1.IsBusy)
            {
                this.backgroundWorker1.CancelAsync();
            }

        }


        private void menu_ShowWebPage_Click(object sender, EventArgs e)
        {
            WebForm web = new WebForm();
            web.Show();
        }

        void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            this.Invoke(new UpdateFormControlDelegate(a =>
            {
                win7SuperIcon.SetState(this.Handle, TBPFLAG.TBPF_NOPROGRESS);
                Log.Message("##运行已经停止。##");
                SetWorkStatus(false);
                notifyIcon1.ShowBalloonTip(3000, "12306", "运行已经停止。", ToolTipIcon.Info);
            }),
            "");

        }

        void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;
            OrderData odata = lst_trainDetail.Tag as OrderData;
            UserData user = e.Argument as UserData;

            if (user == null)
            {
                return;
            }


            Log.Message("开始运行， 查询超时约{1}分钟后停止, 点击 {0} 可以立刻停止。", menu_cancel.Text, WORKER_TIMEOUT_MINUTES);


            System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();
            watch.Start();
            bool result = false;
            while (watch.Elapsed.TotalMinutes < WORKER_TIMEOUT_MINUTES)
            {

                if ((worker.CancellationPending == true))
                {
                    e.Cancel = true;
                    break;
                }
                else
                {
                    result = UserOpration.Instance.QueryLeftTicket(odata.train_date,
                            ref odata.from_station_telecode,
                            ref odata.to_station_telecode,
                            odata.trainno,
                            ref odata);

                    if (result)
                        break;

                    Thread.Sleep(1000);
                }

                int percent = (int)(100 * watch.Elapsed.TotalMinutes / WORKER_TIMEOUT_MINUTES);
                percent = percent < 30 ? 30 : percent; //for virsual effort set to 30%
                worker.ReportProgress(percent);
            }

            if (result == false)
            {
                Log.Error("车次信息不可用， 停止提交。 ");
                return;
            }




            UserOpration.Instance.SubmitOrderRequest(odata, user, captchaHandle);

        }

        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            win7SuperIcon.SetState(this.Handle, TBPFLAG.TBPF_NORMAL);
            win7SuperIcon.SetProgress(this.Handle, (ulong)e.ProgressPercentage, 100);
        }



        protected override void OnClosing(CancelEventArgs e)
        {
            menu_cancel_Click(menu_cancel, null);

            if (txt_userFromStation.Text != null)
                Configurations.txt_userFromStation = txt_userFromStation.Text.ToString();
            if (txt_userToStation.Text != null)
                Configurations.txt_userToStation = txt_userToStation.Text.ToString();
            if (txt_userTrains.Text != null)
                Configurations.txt_userTrains = txt_userTrains.Text.ToString();


            Properties.Settings.Default.Save();
            Configurations.Save();
            base.OnClosing(e);
        }

        #region private func

        private void SetWorkStatus(bool isworking = true)
        {
            menu_status.Text = isworking ? "正在查询" : "Ready";
            menu_start.Enabled = !isworking;
            group_login.Enabled = !isworking;
            group_webform.Enabled = !isworking;

            menu_cancel.Enabled = isworking;
        }

        private void InitializeControlsFromSetting()
        {
            string procName = System.Diagnostics.Process.GetCurrentProcess().ProcessName;
            int pCount = System.Diagnostics.Process.GetProcessesByName(procName).Length - 1;


            this.StartPosition = FormStartPosition.Manual;
            this.Location = new Point(
                Screen.PrimaryScreen.WorkingArea.Width - Width - 400 * pCount,
                100 * pCount);
            this.Icon = Icon.ExtractAssociatedIcon(Environment.ExpandEnvironmentVariables("%windir%" + @"\system32\winver.exe"));
            this.notifyIcon1.Icon = this.Icon;
            txt_dateTimePicker.Value = DateTime.Today.Add(new TimeSpan(ORDER_DAY_AHEAD, 0, 0, 0));
            chk_userSeatTypes.Items.AddRange(Configurations.chk_userSeatTypes.Split(','));
            Log.Add(new FormLog(this.txt_log));


            foreach (string p in Properties.Settings.Default.webProxy)
            {
                ToolStripMenuItem menuItem = new ToolStripMenuItem(p);
                menuItem.Click += (object sender, EventArgs e) =>
                {
                    foreach (ToolStripMenuItem i in Proxy_toolStripMenuItem.DropDownItems)
                    {
                        i.CheckState = CheckState.Unchecked;
                    }

                    ToolStripMenuItem item = sender as ToolStripMenuItem;
                    item.CheckState = CheckState.Checked;

                    UserOpration.Instance.ProxyName = item.Text;
                };

                Proxy_toolStripMenuItem.DropDownItems.Add(menuItem);
            }


            KeyPressEventHandler submitHandler = delegate(object sender, KeyPressEventArgs e)
            {
                if (e.KeyChar == (char)Keys.Enter)
                {
                    btn_login_Click(btn_login, EventArgs.Empty);
                    e.Handled = true;
                }
            };
            txt_userWebName.KeyPress += submitHandler;
            txt_userWebPassword.KeyPress += submitHandler;

        }


        private void InitializeCaptchaDelegate()
        {
            UpdateFormControlDelegate updateImage = new UpdateFormControlDelegate(arg =>
            {

                if (!cb_autoCaptcha.Checked)
                {
                    this.BringToFront();
                    this.Activate();

                    txt_webCaptcha.Focus();
                }
                user_imageBox.Image = arg as Image;
                lbl_userCaptchaInfo.Text = "60秒内输入验证码, 不区分大小写。";
            });

            UpdateFormControlDelegate clearCaptchaCode = new UpdateFormControlDelegate(arg =>
            {
                this.TopMost = false;
                txt_webCaptcha.Text = string.Empty;
                user_imageBox.Image = null;
                lbl_userCaptchaInfo.Text = string.Empty;
            });

            UpdateFormControlDelegate updateAutoCaptcha = new UpdateFormControlDelegate(arg =>
            {
                txt_webCaptcha.Text = arg as string;
            });

            captchaHandle = (img) =>
            {
                if (img == null)
                {
                    Log.Error("出现错误， 不能获取验证码。 ");
                    return string.Empty;
                }

                ImageUtil.GrayImage(ref img);
                this.Invoke(updateImage, img);
                if (cb_autoCaptcha.Checked)
                {
                    tessnet2.Tesseract tessocr = new tessnet2.Tesseract();
                    tessocr.SetVariable("tessedit_char_whitelist", "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ");
                    tessocr.Init(null, "eng", false); // To use correct tessdata
                    List<tessnet2.Word> result = tessocr.DoOCR(new Bitmap(img), Rectangle.Empty);
                    string _result = result[0].Text.Trim();
                    if(_result.Length<4)
                    {
                        _result = "1234";
                    }
                    this.Invoke(updateAutoCaptcha, _result);
                    //txt_webCaptcha.Text = result[0].Text.Trim();
                    Log.Error("验证码为：" + result[0].Text.Trim() + "置信度为：" + result[0].Confidence);
                }
                else
                {
                    Log.Error("!!!!!!!!! 输入验证码 !!!!!!!!!!!");
                }


                int i = 0;
                while (i++ < 20)
                {
                    Thread.Sleep(2000);
                    if (txt_webCaptcha.Text.Length >= 4)
                        break;

                    CheckThreadStateToAbort();
                }

                string ret = txt_webCaptcha.Text;
                this.Invoke(clearCaptchaCode, "");
                return ret;
            };
        }


        private void InitializeBackgroundWorker()
        {
            this.backgroundWorker1.WorkerSupportsCancellation = true;
            this.backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
            this.backgroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
        }

        private void CheckThreadStateToAbort()
        {
            if (this.IsDisposed || Thread.CurrentThread.ThreadState == ThreadState.AbortRequested)
                Thread.CurrentThread.Abort();
        }


        private string FindCodeByChineseName(string name)
        {
            var rows = Global.StationNameTable.Select(string.Format("{0}='{1}'", Global.DataComlumnChineseName, name));
            string code = rows[0][Global.DataComlumnCodeName] as string;

            return code;
        }

        #endregion






    }
}
